package com.gengzp.rpc.core.impl;

import com.gengzp.rpc.core.RpcCacheCoreFunc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.gengzp.rpc.constants.RpcBeanNameConstants.RPC_REDIS_TEMPLATE;

/**
 * @ClassName RpcCacheCoreFuncImpl
 * @Description rpc框架缓存操作核心方法实现类
 * @Author gengzp
 * @Date 2025/8/22 21:44
 */
@Component
public class RpcCacheCoreFuncImpl implements RpcCacheCoreFunc {

    @Autowired
    @Qualifier(RPC_REDIS_TEMPLATE)
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public String get(String key) {
        if (key == null || key.isBlank()) {
            return null;
        }
        Object obj = redisTemplate.opsForValue().get(key);
        if (obj == null) {
            return null;
        }
        return obj.toString();
    }

    @Override
    public void set(String key, String value) {
        if (key == null || key.isBlank()) {
            return;
        }
        redisTemplate.opsForValue().set(key, value);
    }

    @Override
    public void set(String key, String value, Long timeout, TimeUnit timeUnit) {
        if (key == null || key.isBlank()) {
            return;
        }
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    @Override
    public void del(String key) {
        if (key == null || key.isBlank()) {
            return;
        }
        redisTemplate.delete(key);
    }

    @Override
    public List<String> scanKeys(String prefix, int count) {
        Set<String> resultSet = new HashSet<>();

        redisTemplate.execute((RedisCallback<Void>) connection -> {
            try (Cursor<byte[]> cursor = connection.scan(
                    ScanOptions.scanOptions().match(prefix + "*").count(count).build()
            )) {
                while (cursor.hasNext()) {
                    // 3. 使用RedisTemplate配置的序列化器解码
                    byte[] keyBytes = cursor.next();
                    String key = redisTemplate.getStringSerializer().deserialize(keyBytes);
                    if (key != null) {
                        resultSet.add(key);
                    }
                }
            }
            return null;
        });

        // 转换为List返回
        return new ArrayList<>(resultSet);
    }

    @Override
    public List<String> multiGet(List<String> keys) {
        if (keys == null || keys.isEmpty()) {
            return Collections.emptyList();
        }

        // 临时接收结果, 用于类型转换
        List<Object> objects = redisTemplate.opsForValue().multiGet(keys);
        if (objects == null || objects.isEmpty()) {
            return Collections.emptyList();
        }

        // 以字符串的方式返回
        return objects.stream().map(String::valueOf).collect(Collectors.toList());
    }

}
